package com.yonyou.pmclouds.projectpart.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.projectpart.entity.ProjectPartRefVO;
import com.yonyou.pmclouds.projectpart.entity.ProjectPartVO;
import com.yonyou.pmclouds.projectpart.mapper.ProjectpartMapper;
import com.yonyou.pmclouds.projectpart.service.IProjectpartQryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service(interfaceClass = IProjectpartQryService.class, version = ApplicationConsts.APPLICATION_VERSION)
public class ProjectpartQryServiceImpl implements IProjectpartQryService {

    @Autowired
    private ProjectpartMapper projectpartMapper;

    private final String pkProjectpart = "pkProjectpart";
    private final String projectpartName = "projectpartName";

    @Override
    public ProjectPartVO queryVOsByCondition(ProjectPartVO para) {
        List<ProjectPartVO> dbResult = projectpartMapper.queryVOsByCondition(para);

        ProjectPartVO topVirtualVO = new ProjectPartVO();
        topVirtualVO.setSname("工程部位");
        topVirtualVO.setPkProjectpart("topVirtual");
        topVirtualVO.setScode("topVirtual");
        topVirtualVO.setPkProject(para.getPkProject());

        if(dbResult.size() > 0){
            ProjectPartVO[] rootChild = buildWebData(dbResult);
            topVirtualVO.setChildProjectpart(rootChild);

        }
        return topVirtualVO;
    }

    private ProjectPartVO[] buildWebData(List<ProjectPartVO> dbResult){
        //父子关系缓存
        Map<String,List<ProjectPartVO>> mapTemp = new HashMap<String,List<ProjectPartVO>>();
        Map<String,ProjectPartVO> pkCodeMap = new HashMap<String,ProjectPartVO>();
        for(ProjectPartVO vo : dbResult){
            pkCodeMap.put(vo.getPkProjectpart(),vo);
            if(mapTemp.get(vo.getPkParent()) == null){
                List<ProjectPartVO> child = new ArrayList<ProjectPartVO>();
                child.add(vo);
                mapTemp.put(vo.getPkParent(),child);
            }else{
                List<ProjectPartVO> childList = mapTemp.get(vo.getPkParent());
                childList.add(vo);
            }
        }
        List<ProjectPartVO> result = new ArrayList<ProjectPartVO>();
        for(ProjectPartVO vo : dbResult){
            if(pkCodeMap.get(vo.getPkParent()) != null){
                vo.setPcode(pkCodeMap.get(vo.getPkParent()).getScode());
                vo.setParentInnerCode(pkCodeMap.get(vo.getPkParent()).getInnerCode());
                vo.setPname(pkCodeMap.get(vo.getPkParent()).getSname());
            }else{
                vo.setPkParent("topVirtual");
                vo.setPcode("topVirtual");
                result.add(vo);
            }
            if(mapTemp.get(vo.getPkProjectpart()) != null){
                vo.setChildProjectpart(mapTemp.get(vo.getPkProjectpart()).toArray(new ProjectPartVO[]{}));
            }
        }
        return result.toArray(new ProjectPartVO[]{} );
    }

    @Override
    public List<ProjectPartRefVO> queryRefVOs(String pkProject) throws BusinessException {
        if (StringUtils.isEmpty(pkProject))
            return new ArrayList<>(0);

        try {
            return projectpartMapper.queryRefVOs(pkProject);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException();
        }
    }

    @Override
    public List<ProjectPartVO> queryVOByPKs(List<String> pks) {

        if (CollectionUtils.isEmpty(pks)) {
            return null;
        }
        String pksStr = pks.stream()
                .filter(pk -> StringUtils.isNotEmpty(pk))
                .map(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        return "'"+s+"'";
                    }
                }).collect(Collectors.joining(","));
        return projectpartMapper.getByIdsWithoutDr(pksStr);
    }

    //填充工程部位名称
    public void fillProjectpartName (SuperVO[] vos) throws  BusinessException{
        try {
            if(ArrayUtils.isEmpty(vos)){
                return;
            }
            Map<String,SuperVO> PkObjMap = new HashMap<>();
            for(SuperVO vo : vos){
                if(vo == null){
                    continue;
                }
                String pkProjectpartVal = (String) BeanHelper.getGetMethod(vo,pkProjectpart).invoke(vo);
                if(!StringUtils.isEmpty(pkProjectpartVal) && !"~".equals(pkProjectpartVal)){
                    PkObjMap.put(pkProjectpartVal,vo);
                }
            }
            if(PkObjMap.isEmpty()){
                return ;
            }
            List<ProjectPartVO> projectPartList =  this.queryVOByPKs(new ArrayList<>(PkObjMap.keySet()));
            if(!CollectionUtils.isEmpty(projectPartList)){
                for(ProjectPartVO projectPartVO : projectPartList){
                    if(PkObjMap.get(projectPartVO.getPkProjectpart()) != null){
                        SuperVO vo = PkObjMap.get(projectPartVO.getPkProjectpart());
                        BeanHelper.getSetMethod(vo,projectpartName).invoke(vo,projectPartVO.getSname());
                    }
                }
            }
        }catch (IllegalAccessException e){
            log.error(e.getMessage(),"没有访问权限");
            throw new BusinessException("没有访问权限");
        }catch(IllegalArgumentException e2){
            log.error(e2.getMessage(),"参数异常");
            throw new BusinessException("参数异常");
        }catch (InvocationTargetException e3){
            log.error(e3.getMessage(),"反射目标异常");
            throw new BusinessException("反射目标异常");
        }
    }

    @Override
    public void fillProjectpartName(SuperVO vo) throws BusinessException {
        if(vo == null){
            return ;
        }
        List<SuperVO> vos = new ArrayList<>();
        vos.add(vo);
        this.fillProjectpartName(vos.toArray(new SuperVO[]{}));
    }
}
